package com.xcc.shopanim.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.xcc.shopanim.R;

public class VerticalDrawerLayout extends LinearLayout {
    public VerticalDrawerLayout(Context context) {
        super(context);
        init(context, null);
    }

    public VerticalDrawerLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public VerticalDrawerLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public VerticalDrawerLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    public void init(Context context, @Nullable AttributeSet attrs) {
        setOrientation(LinearLayout.VERTICAL);
        if (attrs != null) {//reference
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalDrawerLayout);
            buttonId = a.getResourceId(R.styleable.VerticalDrawerLayout_buttonId, 0);
            contentId = a.getResourceId(R.styleable.VerticalDrawerLayout_contentId, 0);
            a.recycle();
        }
    }

    private int buttonId, contentId;
    private int contentHeight, buttonViewHeight;
    private View buttonView;
    private boolean onTouchButton;
    private float startX, startY, oldY;
    private boolean currOpen;//当期展开状态
    private int openHeight;//展开范围 就是最大的paddingTop
    private OnVerticalDrawerListener onVerticalDrawerListener;

    public VerticalDrawerLayout setOnVerticalDrawerListener(OnVerticalDrawerListener onVerticalDrawerListener) {
        this.onVerticalDrawerListener = onVerticalDrawerListener;
        return this;
    }

    public boolean isCurrOpen() {
        return currOpen;
    }

    /**
     * 提供给外部控制开启或关闭
     */
    public VerticalDrawerLayout setOpen(boolean currOpen) {
        if (currOpen) {
            if (!this.currOpen) {
                this.currOpen = currOpen;
                if (onVerticalDrawerListener != null)
                    onVerticalDrawerListener.onChangeOpen(currOpen);
                //执行关闭
                int paddingTop = getPaddingTop();
                startAnim(paddingTop, -contentHeight);
            }
        } else if (this.currOpen) {//执行开启
            this.currOpen = currOpen;
            if (onVerticalDrawerListener != null)
                onVerticalDrawerListener.onChangeOpen(currOpen);
            int paddingTop = getPaddingTop();
            startAnim(paddingTop, getOpenHeight());
        }
        return this;
    }

    public int getContentHeight() {
        return contentHeight;
    }

    public int getButtonViewHeight() {
        return buttonViewHeight;
    }

    private int getOpenHeight() {
        if (openHeight == 0) {
            final int height = getHeight();
            openHeight = height - contentHeight - buttonViewHeight;
        }
        return openHeight;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        final int height = contentHeight > 0 ? getMeasuredHeight() : 0;
        if (height > 0) openHeight = height - contentHeight - buttonViewHeight;
        if (buttonView != null) return;
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (contentId == child.getId()) {
                contentHeight = child.getMeasuredHeight();
            } else if (buttonId == child.getId()) {
                buttonView = child;
                buttonViewHeight = child.getMeasuredHeight();
            }
        }
        setPadding(getPaddingLeft(), -contentHeight, getPaddingRight(), getPaddingBottom());
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //if (!BuildConfig.DEBUG) return super.dispatchTouchEvent(ev);
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (buttonView != null) {
                    startX = ev.getX();
                    startY = ev.getY();
                    oldY = startY;
                    final int left = buttonView.getLeft();
                    final int right = buttonView.getRight();
                    final int top = buttonView.getTop();
                    final int bottom = buttonView.getBottom();
                    if (startX > left && startX < right && startY > top && startY < bottom) {
                        onTouchButton = true;
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (onTouchButton) {
                    //float x = ev.getX();
                    float y = ev.getY();
                    float len = y - oldY;
                    oldY = y;
                    int paddingTop = getPaddingTop();
                    setPadding(getPaddingLeft(), (int) (paddingTop + len), getPaddingRight(), getPaddingBottom());
                }
                break;
            case MotionEvent.ACTION_UP:
                if (onTouchButton) {
                    //float x = ev.getX();
                    //float y = ev.getY();
                    oldY = ev.getY();
                    final boolean down = oldY > startY;//向下滑动
                    final int paddingTop = getPaddingTop();
                    if (currOpen) {//展开状态
                        final int openHeight = getOpenHeight();//最大展开
                        if (down) {//恢复原位
                            startAnim(paddingTop, openHeight);
                        } else {//向上
                            int contentHeight = getContentHeight();
                            int i = (openHeight - paddingTop) << 1;
                            if (i > contentHeight) {//开始关闭
                                startAnim(paddingTop, -contentHeight);
                                currOpen = false;
                                if (onVerticalDrawerListener != null) {
                                    onVerticalDrawerListener.onChangeOpen(currOpen);
                                }
                            } else startAnim(paddingTop, openHeight);
                        }
                    } else {//关闭状态
                        int contentHeight = getContentHeight();
                        if (down) {//向下
                            int i = (paddingTop + contentHeight) << 1;
                            if (i > contentHeight) {//展开
                                startAnim(paddingTop, getOpenHeight());
                                currOpen = true;
                                if (onVerticalDrawerListener != null) {
                                    onVerticalDrawerListener.onChangeOpen(currOpen);
                                }
                            } else startAnim(paddingTop, -contentHeight);
                        } else startAnim(paddingTop, -contentHeight);//恢复原位
                    }
                }
                onTouchButton = false;
                break;
        }
        if (onTouchButton) {
            getParent().requestDisallowInterceptTouchEvent(true);
            return true;
        } else return super.dispatchTouchEvent(ev);
    }

    private void startAnim(float startY, float endY) {
        if (startY == endY) return;
        ValueAnimator animator = ValueAnimator.ofFloat(startY, endY);
        animator.setDuration(300);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(animation -> {
            Object animatedValue = animation.getAnimatedValue();
            if (animatedValue instanceof Float) {
                Float f = (Float) animatedValue;
                setPadding(getPaddingLeft(), f.intValue(), getPaddingRight(), getPaddingBottom());
            }
        });
        animator.start();
    }

    @Override
    public void setPadding(int left, int top, int right, int bottom) {
        super.setPadding(left, top, right, bottom);
        if (onVerticalDrawerListener == null) return;
        onVerticalDrawerListener.onContentOffset(top);
    }

    public interface OnVerticalDrawerListener {
        void onChangeOpen(boolean open);

        void onContentOffset(int paddingTop);
    }
}
